package com.hanxiaozhang.jdk8;

import com.hanxiaozhang.commomentity.Student;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author hanxinghua
 * @create 2022/7/19
 * @since 1.0.0
 */
public class No2Optional {

    public static void main(String[] args) {


        /*
        一、Optional介绍
        Optional类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true，调用get()方法会返回该对象。
        Optional是个容器：它可以保存类型T的值，或者仅仅保存null。Optional提供很多有用的方法，这样我们就不用显式进行空值检测。
        Optional类的引入很好的解决空指针异常。
         */


        // 二、构建一个Optional对象；方法有：empty()、of()、ofNullable()
        // empty():返回一个空的Optional实例，此Optional没有值。  Optional.empty()的 final T value 是 null
        System.out.println("Optional.empty(): " + Optional.empty());

        // of():返回一个携带被指定的value，且该value不能为NULL，否则抛空指针异常；
        System.out.println("Optional.of(1): " + Optional.of(1));
        // System.out.println("Optional.of(null): "+Optional.of(null))

        // ofNullable():如果指定的value不为null，则返回携带有该value的Optional，如果为null，则返回Optional.empty
        System.out.println("Optional.ofNullable(1): " + Optional.ofNullable(1));
        System.out.println("Optional.ofNullable(null): " + Optional.ofNullable(null));


        // 三、获取值：get()、orElse()、orElseGet()、orElseThrow()
        Optional empty = Optional.empty();
        Optional<Integer> one = Optional.of(1);

        // get()：直接获取值，如果Optional是EMPTY，即是null，会抛NoSuchElementException
        System.out.println("one.get(): " + one.get());
        // System.out.println("empty.get(): "+empty.get())

        // orElse(): 如果存在，则返回值，否则返回orElse的值。
        System.out.println("empty.orElse(2): " + empty.orElse(2));

        // orElseGet(): 如果存在，则返回值，否则返回orElseGet传入的lambda表达式的返回值。
        System.out.println("empty.orElseGet(() -> Integer.parseInt(\"2\")): " + empty.orElseGet(() -> Integer.parseInt("2")));

        // orElseThrow(): 如果存在，则返回值，否则返回orElseThrow抛出的异常
        try {
            empty.orElseThrow(NullPointerException::new);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }


        // 四、判断：isPresent()、ifPresent()
        // isPresent()：如果存在值，则返回true，否则返回false
        System.out.println("empty.isPresent(): " + empty.isPresent());

        // ifPresent(): 如果存在值，则使用值调用指定的使用者，否则不执行任何操作
        // 作用：替代如下写法
        // if(student != null){
        //  student.setAddress("北京顺义")
        // }
        Student student = new Student("1", "小张", "北京朝阳");
        Optional<Student> studentOptional = Optional.ofNullable(student);
        studentOptional.ifPresent(x -> x.setAddress("北京顺义"));
        System.out.println("ifPresent(): "+student);


        // 五、条件过滤：filter() ：如果包含的值满足条件，那么还是返回这个 Optional；否则返回 Optional.empty
        Optional<Student> studentOptionalFilter = studentOptional.filter(x -> x.getName().length() > 2);
        System.out.println("filter(): "+studentOptionalFilter);

        // 六、转换：map()：
        Optional<String> name = studentOptional.map(Student::getName);
        System.out.println("map(): "+name);


        // 七、小思考题：
        System.out.println("orElse ---- ----");
        // do invoke 会执行
        Optional.of("has value").orElse(getDefault());
        System.out.println("orElseGet ---- ----");
        // 不会执行
        Optional.of("has value").orElseGet(() -> getDefault());



        List<String> list =null;
        Optional.ofNullable(list).orElse(new ArrayList<>(0));


    }

    public static String getDefault() {
        System.out.println("do invoke");
        return "default";
    }

}


